package com.ideaaedi.zoo.commonbase.component.tenant.annotation;

import com.ideaaedi.commonds.function.NoArgConsumer;
import com.ideaaedi.commonds.function.NoArgFunction;
import com.ideaaedi.zoo.commonbase.constant.ZooConstant;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.Collection;

/**
 * 租户和数据范围注解
 * <p>
 * 支持指定 租户、可读数据范围、可写数据范围
 *
 * @author <font size = "20" color = "#3CAA3C"><a href="https://gitee.com/JustryDeng">JustryDeng</a></font> <img
 * src="https://gitee.com/JustryDeng/shared-files/raw/master/JustryDeng/avatar.jpg" />
 * @since 1.0.0
 */
@Target(value = ElementType.METHOD)
@Retention(value = RetentionPolicy.RUNTIME)
public @interface Tenant {
    
    /**
     * <ul>
     *     <li>
     *         {@link Mode#POINT_URD}模式下，数据（删改查）的租户值
     *         <p>
     *         注1：此时新增则依旧保持用户原查询租户值
     *         <p>
     *         注2：此模式下，支持spel。 spel示例："#{#sys.username}"）
     *     </li>
     *     <li>
     *         {@link Mode#POINT_CURD}模式下，数据（增删改查）的默认租户值
     *         <p>
     *         注：此模式下，支持spel。 spel示例："#{#sys.username}"）
     *     </li>
     * </ul>
     */
    String value() default ZooConstant.EMPTY;
    
    /**
     * <ul>
     *     <li>{@link Mode#POINT_URD}模式下，此字段将被忽略</li>
     *     <li>
     *         {@link Mode#POINT_CURD}模式下，插入（insert）时的租户值
     *         <p>
     *         注1：字段优先级高于{@link #value}
     *         <p>
     *         注2：此模式下，支持spel。 spel示例："#{#sys.username}"）
     *     </li>
     * </ul>
     */
    String insertTenant() default ZooConstant.EMPTY;
    
    /**
     * <ul>
     *     <li>{@link Mode#POINT_URD}模式下，此字段将被忽略</li>
     *     <li>
     *         {@link Mode#POINT_CURD}模式下，查询（select）时的租户值
     *         <p>
     *         注1：字段优先级高于{@link #value}
     *         <p>
     *         注2：支持spel。 spel示例："#{#sys.username}"）
     *     </li>
     * </ul>
     */
    String[] readableTenants() default {};
    
    /**
     * <ul>
     *     <li>{@link Mode#POINT_URD}模式下，此字段将被忽略</li>
     *     <li>
     *         {@link Mode#POINT_CURD}模式下，修改、删除（update、delete）时的租户值
     *         <p>
     *         注1：字段优先级高于{@link #value}
     *         <p>
     *         注2：支持spel。 spel示例："#{#sys.username}"）
     *     </li>
     * </ul>
     */
    String[] modifiableTenants() default {};
    
    /**
     * 模式
     */
    Mode mode() default Mode.POINT_URD;
    
    /**
     * 模式
     *
     * @since 1.0.7
     */
    enum Mode {
        
        /**
         * 以{@link #value}作为删改查（URD）的租户值，  增（C）则依旧保持用户原查询租户值
         * <pre>
         *  注1： 此模式下，{@link #insertTenant}、{@link #readableTenants}、{@link #modifiableTenants}字段将被忽略
         *
         *  注2：此时，注解效果与直接调用方法
         *      {@link com.ideaaedi.zoo.diy.artifact.tenant.tenant.TenantProvider#execGlobal}、
         *      {@link com.ideaaedi.zoo.diy.artifact.tenant.tenant.TenantProvider#voidExecGlobal(NoArgConsumer)}
         *      效果一致
         * </pre>
         */
        POINT_URD,
    
    
        /**
         * 以{@link #insertTenant}作为增（C）的租户值，
         * 以{@link #readableTenants}作为查（R）的租户值，
         * 以{@link #modifiableTenants}作为删改（UD）的租户值，
         * 以{@link #value}作为增删改查（CURD）的默认租户值
         * <pre>
         *  注1： {@link #value}优先级低于{@link #insertTenant}、{@link #readableTenants}、{@link #modifiableTenants}
         *
         *  注2：此时，注解效果与直接调用方法
         *      {@link com.ideaaedi.zoo.diy.artifact.tenant.tenant.TenantProvider#exec(NoArgFunction, String, Collection, Collection)}、
         *      {@link com.ideaaedi.zoo.diy.artifact.tenant.tenant.TenantProvider#voidExec(NoArgConsumer, String, Collection, Collection)}
         *      效果一致
         * </pre>
         */
        POINT_CURD
    }
}
